package com.example.my_add_calendar

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.ContentResolver
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.content.pm.PackageManager
import android.database.Cursor
import android.graphics.Color
import android.icu.util.TimeZone
import android.net.Uri
import android.os.Build
import android.provider.CalendarContract
import android.util.Log
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class CalendarProviderUtil {
    companion object {
        private const val REQUEST_CODE_ASK_PERMISSIONS = 123

        // ContentProvider的uri
        private val calendarUri: Uri = CalendarContract.Calendars.CONTENT_URI
        private val eventUri: Uri = CalendarContract.Events.CONTENT_URI
        private val reminderUri: Uri = CalendarContract.Reminders.CONTENT_URI

        private lateinit var contentResolver: ContentResolver

        fun checkCalendarReadPermission(context: Context): Boolean {
            //判断是否已经赋予权限
            //读日历权限
            if (ContextCompat.checkSelfPermission(
                    context,
                    Manifest.permission.READ_CALENDAR
                )
                != PackageManager.PERMISSION_GRANTED
            ) {
                //如果应用之前请求过此权限但用户拒绝了请求，此方法将返回 true。
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        context as Activity,
                        Manifest.permission.READ_CALENDAR
                    )
                ) { //这里可以写个对话框之类的项向用户解释为什么要申请权限，并在对话框的确认键后续再次申请权限.它在用户选择"不再询问"的情况下返回false
                } else {
                    //申请权限，字符串数组内是一个或多个要申请的权限，1是申请权限结果的返回参数，在onRequestPermissionsResult可以得知申请结果
                    ActivityCompat.requestPermissions(
                        context,
                        arrayOf<String>(Manifest.permission.READ_CALENDAR),
                        CalendarProviderUtil.REQUEST_CODE_ASK_PERMISSIONS
                    )
                }
                return false
            } else {
                return true
            }
        }

        fun checkCalendarWritePermission(context: Context): Boolean {
            //判断是否已经赋予权限
            //写日历权限
            if (ContextCompat.checkSelfPermission(
                    context,
                    Manifest.permission.WRITE_CALENDAR
                )
                != PackageManager.PERMISSION_GRANTED
            ) {
                //如果应用之前请求过此权限但用户拒绝了请求，此方法将返回 true。
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        context as Activity,
                        Manifest.permission.WRITE_CALENDAR
                    )
                ) { //这里可以写个对话框之类的项向用户解释为什么要申请权限，并在对话框的确认键后续再次申请权限.它在用户选择"不再询问"的情况下返回false
                } else {
                    //申请权限，字符串数组内是一个或多个要申请的权限，1是申请权限结果的返回参数，在onRequestPermissionsResult可以得知申请结果
                    ActivityCompat.requestPermissions(
                        context,
                        arrayOf(Manifest.permission.WRITE_CALENDAR), REQUEST_CODE_ASK_PERMISSIONS
                    )
                }
                return false
            } else {
                return true
            }
        }

        /**
         * 检查是否有日历表,有返回日历id，没有-1
         */
        @SuppressLint("Range")
        private fun isHaveCalender(context: Context): Int {
            // 查询日历表的cursor

            val cursor: Cursor? = CalendarProviderUtil.contentResolver.query(
                CalendarProviderUtil.calendarUri,
                null,
                null,
                null,
                null
            )
            if (cursor == null || cursor.count == 0) {
                return -1
            } else {
                // 如果有日历表
                try {
                    cursor.moveToFirst()
                    // 通过cursor返回日历表的第一行的属性值 第一个日历的id
                    return cursor.getInt(cursor.getColumnIndex(CalendarContract.Calendars._ID))
                } finally {
                    cursor.close()
                }
            }
        }

        private fun asSyncAdapter(uri: Uri, account: String, accountType: String): Uri {
            return uri.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, account)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, accountType).build()
        }
        /**
         * 添加日历表
         */
        @RequiresApi(api = Build.VERSION_CODES.N)
        private fun addCalendar(context: Context): Long {
            // 时区
            val timeZone = TimeZone.getDefault()
            // 配置Calendar
            val value = ContentValues()
            value.put(CalendarContract.Calendars.NAME, "我的日历表")
            value.put(CalendarContract.Calendars.ACCOUNT_NAME, "myAccount")
            value.put(CalendarContract.Calendars.ACCOUNT_TYPE, "myType")
            value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "myDisplayName")
            value.put(CalendarContract.Calendars.VISIBLE, 1)
            value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE)
            value.put(
                CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL,
                CalendarContract.Calendars.CAL_ACCESS_OWNER
            )
            value.put(CalendarContract.Calendars.SYNC_EVENTS, 1)
            value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.id)
            value.put(CalendarContract.Calendars.OWNER_ACCOUNT, "myAccount")
            value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0)
//            value.put(CalendarContract.CALLER_IS_SYNCADAPTER, true)

            // 插入calendar
//            val insertCalendarUri = contentResolver.insert(calendarUri, value)
            val insertCalendarUri = contentResolver.insert(asSyncAdapter(calendarUri, "myAccount", "myType"), value)

            return if (insertCalendarUri == null) {
                -1
            } else {
                // return Integer.parseInt(insertCalendarUri.toString());
                ContentUris.parseId(insertCalendarUri)
            }
        }

        /**
         * 添加日历事件
         *
         * @return
         * */
        @RequiresApi(api = Build.VERSION_CODES.N)
        fun addEvent(context: Context, calendars: Calendars): String {
            // 创建contentResolver

            contentResolver = context.contentResolver

            // 日历表id
            var calendarId = isHaveCalender(context)
            if (calendarId == -1) {
                addCalendar(context)
                calendarId = isHaveCalender(context)
            }

            Log.i("TAG", "STStart " + calendars.beginTime)
            // 准备event
            val valueEvent = ContentValues()
            valueEvent.put(CalendarContract.Events.DTSTART, calendars.beginTime)
            valueEvent.put(CalendarContract.Events.DTEND, calendars.endTime)
            valueEvent.put(CalendarContract.Events.TITLE, calendars.title)
            valueEvent.put(CalendarContract.Events.DESCRIPTION, calendars.note)
            valueEvent.put(CalendarContract.Events.CALENDAR_ID, calendarId)
            valueEvent.put(CalendarContract.Events.EVENT_TIMEZONE, "Asia/Shanghai")
            valueEvent.put(CalendarContract.Events.ALL_DAY, calendars.allDay)

            val insertEventUri = contentResolver.insert(eventUri, valueEvent)
            if (insertEventUri == null) {
                Toast.makeText(context, "添加event失败", Toast.LENGTH_SHORT).show()
            }

            // 添加提醒
            val eventId = ContentUris.parseId(insertEventUri!!)
            val valueReminder = ContentValues()
            for (i in calendars.alert) {
                valueReminder.put(CalendarContract.Reminders.EVENT_ID, eventId)
                valueReminder.put(CalendarContract.Reminders.MINUTES, i)
                valueReminder.put(
                    CalendarContract.Reminders.METHOD,
                    CalendarContract.Reminders.METHOD_ALARM
                )
                val insertReminderUri = contentResolver.insert(reminderUri, valueReminder)
                if (insertReminderUri == null) {
                    Toast.makeText(context, "添加失败", Toast.LENGTH_SHORT).show()
                }
            }
            val StringEventId = eventId.toString()
            Log.i("TAG", StringEventId)
            return StringEventId
        }

        //删除事件
        @RequiresApi(api = Build.VERSION_CODES.N)
        fun deleteEvent(context: Context, eventId: String): Boolean {
            contentResolver = context.contentResolver
            // 日历表id
            var calendarId = isHaveCalender(context)
            if (calendarId == -1) {
                addCalendar(context)
                calendarId = isHaveCalender(context)
            }

            val eventID = eventId.toLong()
            if (eventID < 0) {
                Toast.makeText(context, "请输入正确的eventId,ID:$eventId", Toast.LENGTH_SHORT).show()
                return false
            } else {
                val deleteUri: Uri = ContentUris.withAppendedId(eventUri, eventID)
                val res = contentResolver.delete(deleteUri, null, null)
                if (res == -1) {
                    Toast.makeText(context, "删除失败,可能是提醒事件id不存在", Toast.LENGTH_SHORT).show()
                    return false
                } else {
                    return true
                }
            }
        }

        @RequiresApi(api = Build.VERSION_CODES.N)
        fun updateEvent(context: Context, calendars: Calendars): String {
            // 创建contentResolver
            contentResolver = context.contentResolver

            val eventID = calendars.eventId.toLong()
            // 日历表id
            var calendarId = isHaveCalender(context)
            if (calendarId == -1) {
                addCalendar(context)
                calendarId = isHaveCalender(context)
            }

            // 准备event
            val valueEvent = ContentValues()
            valueEvent.put(CalendarContract.Events.DTSTART, calendars.beginTime)
            valueEvent.put(CalendarContract.Events.DTEND, calendars.endTime)
            valueEvent.put(CalendarContract.Events.TITLE, calendars.title)
            valueEvent.put(CalendarContract.Events.DESCRIPTION, calendars.note)
            valueEvent.put(CalendarContract.Events.CALENDAR_ID, calendarId)
            valueEvent.put(CalendarContract.Events.EVENT_TIMEZONE, "Asia/Shanghai")

            //        contentResolver.update(eventUri,valueEvent,eventID,null);
            val updateUri =
                ContentUris.withAppendedId(eventUri, eventID)
            contentResolver.update(updateUri, valueEvent, null, null)

            val valueReminder = ContentValues()
            for (i in calendars.alert) {
                valueReminder.put(CalendarContract.Reminders.EVENT_ID, eventID)
                valueReminder.put(CalendarContract.Reminders.MINUTES, i)
                valueReminder.put(
                    CalendarContract.Reminders.METHOD,
                    CalendarContract.Reminders.METHOD_ALARM
                )
                var updateUri1 =
                    ContentUris.withAppendedId(eventUri, eventID)
                val res = contentResolver.update(updateUri1, valueReminder, null, null)
                if (res == -1) {
                    Toast.makeText(
                        context,
                        ("更新失败" + "ID：" + calendars.eventId).toString() + "标题" + calendars.title,
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }

            return calendars.eventId
        }
    }
}